//==================================================================================================
/*
  EVE - Expressive Vector Engine
  Copyright : EVE Project Contributors
  SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#include "test.hpp"

#include <eve/module/bessel.hpp>

TTS_CASE_TPL ( "Check eve::cyl_bessel_kn over real,  integral orders"
             , eve::test::scalar::ieee_reals
              )
<typename T>(tts::type<T>)
{
  auto constexpr N = 11;
  using a_t  = std::array<T, 8 >;
  using aN_t = std::array<a_t, N >;
  a_t re{2.9999999999999982e-01, 1.0000000000000000e+00, 1.7000000000000002e+00, 2.3999999999999995e+00, 3.0999999999999988e+00, 3.7999999999999998e+00, 4.4999999999999991e+00, 5.2000000000000002e+00};
  aN_t resN8;
  //res are taken from octave 9.2.0 besselj outputs
  int p=0;
  resN8[p] = a_t{1.3724600605442980e+00,4.2102443824070834e-01,1.6549631805699641e-01,7.0217341543415926e-02,3.0954708038041484e-02,1.3965884534245625e-02,6.3998572432339825e-03,2.9657456010295812e-03,};
  ++p; //1  1.000e+00
  resN8[p] = a_t{3.0559920334573265e+00,6.0190723019723458e-01,2.0936248820408246e-01,8.3724838754832206e-02,3.5634054949617543e-02,1.5705729078473500e-02,7.0780949089680979e-03,3.2392637730894558e-03,};
  ++p; //2  2.000e+00
  resN8[p] = a_t{2.1745740283593154e+01,1.6248388986351774e+00,4.1180512770885808e-01,1.3998804050577612e-01,5.3944420908762482e-02,2.2232057733442202e-02,9.5456772027753597e-03,4.2116162829870640e-03,};
  ++p; //3  3.000e+00
  resN8[p] = a_t{2.9299919581469953e+02,7.1012628247379439e+00,1.1783157298719837e+00,3.1703823959779243e-01,1.0523975934802077e-01,3.9107895113675809e-02,1.5563141311435085e-02,6.4789686061564279e-03,};
  ++p; //4  4.000e+00
  resN8[p] = a_t{5.8817296565775869e+03,4.4232415847062839e+01,4.5705665272570348e+00,9.3258363950025736e-01,2.5763427771138336e-01,8.3981365807667144e-02,3.0296532284688808e-02,1.1687349290090635e-02,};
  ++p; //5  5.000e+00
  resN8[p] = a_t{1.5713912337121708e+05,3.6096058960124066e+02,2.2686864093434497e+01,3.4256503712653177e+00,7.7010241150642955e-01,2.1591077049823815e-01,6.9423643150881870e-02,2.4459505975526635e-02,};
  ++p; //6  6.000e+00
  resN8[p] = a_t{5.2438525086971503e+06,3.6538383118594693e+03,1.3802270825334227e+02,1.5206126853105751e+01,2.7418356051514792e+00,6.5216760396092521e-01,1.8457129484220411e-01,5.8724860781488003e-02,};
  ++p; //7  7.000e+00
  resN8[p] = a_t{2.0991123947125733e+08,4.4207020331914879e+04,9.9696480470526194e+02,7.9456284636794095e+01,1.1383659592737965e+01,2.2753874145853699e+00,5.6161376273009300e-01,1.5997841547126815e-01,};
  ++p; //8  8.000e+00
  resN8[p] = a_t{9.8011016945007114e+09,6.2255212295866781e+05,8.3483210999437324e+03,4.7870112056773814e+02,5.4151911185258435e+01,9.0351738682228131e+00,1.9318141122247161e+00,4.8943597935797911e-01,};
  ++p; //9  9.000e+00
  resN8[p] = a_t{5.2293533494617615e+11,1.0005040987670600e+07,7.9569398686528599e+04,3.2707970884217161e+03,2.9087739474245899e+02,4.0318224754470883e+01,7.4302861617513081e+00,1.6659352750342808e+00,};
  ++p; //10  1.000e+01
  resN8[p] = a_t{3.1385921198465086e+13,1.8071328990102947e+08,8.5084783660436387e+05,2.5009679283730620e+04,1.7431174290446984e+03,2.0001623849466378e+02,3.1652958759229957e+01,6.2561350083227971e+00,};
  using eve::spherical;
  auto h =  eve::half(eve::as<T>());
  for(int j=0; j < 8; ++j)
  {
    auto c = re[j];
    auto fac = eve::sqrt(eve::pio_2(eve::as(c))*eve::rec(c));
    for(int i=0; i < N; ++i)
    {
      auto res = resN8[i][j];
      TTS_RELATIVE_EQUAL(eve::bessel_k(i, c), res, tts::prec<T>());
      TTS_RELATIVE_EQUAL(eve::bessel_k(-i, c), res, tts::prec<T>());
      TTS_RELATIVE_EQUAL(eve::bessel_k[spherical](i, c), eve::bessel_k(i+h, c)*fac, tts::prec<T>());
      TTS_RELATIVE_EQUAL(eve::bessel_k[spherical](-i, c), eve::bessel_k(-i+h, c)*fac, tts::prec<T>());
    }
  }
};
